package alog

import (
	"fmt"
	"log"
	"log/slog"
	"os"
	"path/filepath"
	"time"

	"github.com/tidwall/gjson"
)

func InitMyLog(level slog.Level) {
	s := &slog.HandlerOptions{
		AddSource: true,
		Level:     level,
		ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr {
			if a.Key == slog.TimeKey {
				a.Value = slog.AnyValue(a.Value.Time().Format("2006/01/02 15:04:05"))
			}
			return a
		},
	}
	var myout *myWriter
	slog.SetDefault(slog.New(slog.NewJSONHandler(myout, s)))
}

// 自定义实现io.Writer接口，将数据输出到自定义位置
type myWriter struct{}

// Write 实现io.Writer接口的Write方法
func (rw *myWriter) Write(p []byte) (n int, err error) {
	// tp := time.Now().UnixNano() / int64(time.Microsecond)
	tp := time.Now().UnixMicro()
	lg := string(p)
	// 控制台打印
	if gjson.Get(lg, "data").Exists() {
		fmt.Printf("[slog] %s [%s] [%s:%.f] %s\n - %s\n",
			gjson.Get(lg, "level"),
			gjson.Get(lg, "time"),
			gjson.Get(lg, "source.file"),
			gjson.Get(lg, "source.line").Num,
			gjson.Get(lg, "msg"),
			gjson.Get(lg, "data"))
	} else {
		fmt.Printf("[slog] %s [%s] [%s:%.f] %s\n",
			gjson.Get(lg, "level"),
			gjson.Get(lg, "time"),
			gjson.Get(lg, "source.file"),
			gjson.Get(lg, "source.line").Num,
			gjson.Get(lg, "msg"))
	}

	js := fmt.Sprintf(
		`,"appName":"%s","serverName":"%s","env":"%s","_timestamp": %d}`,
		"aijuan",
		"127.0.0.1",
		"dev",
		tp,
	)
	jstr := lg[:len(lg)-2] + js
	if gjson.Valid(jstr) {
		// 写入到文件, 若有性能要求获取大吞吐量，则使用redis作为缓存，异步消费redis实现持久化
		writeToFile(jstr)
	} else {
		// 非json
		fmt.Printf("[Alog] %s [ERROR]\n - Non-json Err", gjson.Get(string(p), "time"))
	}
	return len(p), nil
}

// writeToFile 写入文件
func writeToFile(jstr string) {
	stRootDir, _ := os.Getwd()
	filePath := filepath.Join(stRootDir, "resources", "log.txt")
	// 检查文件大小
	fileInfo, err := os.Stat(filePath)
	if err != nil {
		if !os.IsNotExist(err) {
			log.Fatalf("Error checking log file size: %v", err)
			return
		} else {
			// 创建文件
			if _, err := os.Create(filePath); err != nil {
				log.Fatalf("Error creating log file: %v", err)
				return
			}
		}
	} else {
		const maxFileSize = 5 * 1024 * 1024 // 5MB
		if fileInfo.Size() > maxFileSize {
			// 文件大于5MB，重新创建(会覆盖原文件)
			if _, err := os.Create(filePath); err != nil {
				log.Fatalf("Error creating log file: %v", err)
				return
			}
		}
	}

	// 异步写文件
	go func() {
		// 现在可以安全写入文件，没有大小限制
		file, err := os.OpenFile(filePath, os.O_WRONLY|os.O_APPEND, 0666)
		if err != nil {
			log.Fatalf("Error opening log file: %v", err)
			return
		}
		defer func(file *os.File) {
			err := file.Close()
			if err != nil {
				fmt.Println("close log file err:", err.Error())
			}
		}(file)

		// 写入数据到文件
		if _, err := file.Write([]byte(jstr + "\n")); err != nil {
			log.Fatalf("Error writing to log file: %v", err)
		}
	}()
}
